<template>
  <div class="palette-container">
    <el-tooltip class="item" effect="dark" content="开始" placement="right">
      <div
      class="palette"
      :class="selectElement === 'start'? 'palette-active' : 'palette-active-disable'"
      :draggable="selectElement === 'start'"
      @click="clickElement('start')"
      @dragend="dragendNodeElement">
        <svg-icon icon-class="hexagon" :size="3"></svg-icon>
      </div>
    </el-tooltip>
    <el-tooltip class="item" effect="dark" content="结束" placement="right">
      <div
      class="palette"
      :class="selectElement === 'end'? 'palette-active' : 'palette-active-disable'"
      @click="clickElement('end')"
      :draggable="selectElement === 'end'"
      @dragend="dragendNodeElement">
        <svg-icon icon-class="end" :size="3"></svg-icon>
      </div>
    </el-tooltip>
    <el-tooltip class="item" effect="dark" content="任务" placement="right">
      <div
      class="palette"
      :class="selectElement === 'task'? 'palette-active' : 'palette-active-disable'"
      @click="clickElement('task')"
      :draggable="selectElement === 'task'"
      @dragend="dragendNodeElement">
        <svg-icon icon-class="task" :size="4"></svg-icon>
      </div>
    </el-tooltip>
    <el-tooltip class="item" effect="dark" content="判断" placement="right">
      <div
      class="palette"
      :class="selectElement === 'judge'? 'palette-active' : 'palette-active-disable'"
      @click="clickElement('judge')"
      :draggable="selectElement === 'judge'"
      @dragend="dragendNodeElement">
        <svg-icon icon-class="judge" :size="4"></svg-icon>
      </div>
    </el-tooltip>
  </div>
</template>
<script>
import StartNode from '@/components/process/custom-node/StartNode/index.vue'
import EndNode from '@/components/process/custom-node/EndNode/index.vue'
import TaskNode from '@/components/process/custom-node/TaskNode/index.vue'
import JudgeNode from '@/components/process/custom-node/JudgeNode/index.vue'

import { register } from '@antv/x6-vue-shape'
import { registerPortLayout } from '../graph-layout/index'
import { Graph } from '@antv/x6'

export default {
  name: 'ProcessPalette',
  props: {
    graph: {
      type: Graph,
      default: ()=> null
    }
  },
  data() {
    return {
      selectElement: null,
      startNodeShap: 'process-start-node',
      endNodeShap: 'process-end-node',
      taskNodeShap: 'process-task-node',
      judgeNodeShap: 'process-judge-node',
      currentSelectNode: null
    }
  },
  created() {
    this.$nextTick(()=> {
      this.initGraphNode()
    })
  },
  methods: {
    // 初始化流程节点 注册到graph对象
    initGraphNode() {
      // 开始流程节点
      this.registerNode(this.startNodeShap, 100, 100, StartNode)

      // 结束流程节点
      this.registerNode(this.endNodeShap, 100, 100, EndNode)

      // 任务流程节点
      this.registerNode(this.taskNodeShap, 100, 100, TaskNode)

      // 判断流程节点
      this.registerNode(this.judgeNodeShap, 100, 100, JudgeNode)
    },

    // 添加自定义节点组件到画布
    registerNode(shape, width, height, component) {
      register({
        shape: shape,
        width: width,
        height: height,
        component: component
      })
    },

    // 选择流程节点
    clickElement(type) {
      // 取消选择
      if(this.selectElement === type) {
        this.selectElement = null
      }else {
        this.selectElement = type
      }
    },

    // 添加节点到画布
    dragendNodeElement($event) {
      const id = this.selectElement.concat('-').concat(this.$common.generateRandomNumberString(8)).concat('-').concat(this.$common.generateRandomNumberString(8)).concat('-palette')
      // 开始节点
      if(this.selectElement === 'start'){
        const { node, graph} = this.$parent.drawerNodeToGraph(this.selectElement, id, $event.layerX, $event.layerY, 50, 50, this.startNodeShap)
        // 初始化链接桩配置
        this.setGraphNodePortsConfig(node)

        this.setVueNodePropsData(node, {$parent: this.getCurrentObj, isActive: true, id: node.id, graph: graph, selectNodeFun: this.selectNodeFun})

        // 加载节点连接桩
        this.selectNodeFun(node.id, graph, this.selectElement)

      // 结束节点
      }else if(this.selectElement === 'end') {
        const { node, graph} = this.$parent.drawerNodeToGraph(this.selectElement, id, $event.layerX, $event.layerY, 60, 60, this.endNodeShap)
        // 初始化链接桩配置
        this.setGraphNodePortsConfig(node)

        this.setVueNodePropsData(node, {$parent: this.getCurrentObj, isActive: true, id: node.id, graph: graph, selectNodeFun: this.selectNodeFun})

        // 加载节点连接桩
        this.selectNodeFun(node.id, graph, this.selectElement)

      // 任务节点
      }else if(this.selectElement === 'task') {
        const { node, graph} = this.$parent.drawerNodeToGraph(this.selectElement, id, $event.layerX, $event.layerY, 70, 50, this.taskNodeShap)
         // 初始化链接桩配置
         this.setGraphNodePortsConfig(node)

         this.setVueNodePropsData(node, {$parent: this.getCurrentObj, isActive: true, id: node.id, graph: graph, selectNodeFun: this.selectNodeFun})

         // 加载节点连接桩
         this.selectNodeFun(node.id, graph, this.selectElement)

      // 判断流程节点
      }else if(this.selectElement === 'judge') {
        const { node, graph} = this.$parent.drawerNodeToGraph(this.selectElement, id, $event.layerX, $event.layerY, 100, 120, this.judgeNodeShap)
         // 初始化链接桩配置
         this.setGraphNodePortsConfig(node)

         this.setVueNodePropsData(node, {$parent: this.getCurrentObj, isActive: true, id: node.id, graph: graph, selectNodeFun: this.selectNodeFun})

         // 加载节点连接桩
         this.selectNodeFun(node.id, graph, this.selectElement)
      }
    },

    // 设置节点端口参数(方便重置)
    setGraphNodePortsConfig(node) {
      const ports =  {
          groups: {
            sin: {
              markup: [{
                tagName: 'circle',
                selector: 'circle',
              }],
              attrs: {
                circle: {
                  r: 6,
                  strokeWidth: 2
                },
              },
              position: node.id,
            },
          },
        }
        node.prop('ports', ports)
        this.nodeShowPort(node)
    },

    // 设置自定义节点
    setVueNodePropsData(node, data) {
      setTimeout(()=> {
        node.setData(data)
         // 选择当前节点
        this.$antProcess.selectCurrentProcessNode(data.graph, node.id)

        // 取消选择的节点
        this.$antProcess.cancelNoCurrentSelectNode(data.graph, node.id)
      }, 50)
    },

    // 选择节点之后的回调函数
    selectNodeFun(nodeId, graph, nodeType) {
      this.currentSelectNode = graph.getCellById(nodeId)
      let nodePorts = {}
      if(nodeType === 'start') {
        nodePorts = { left: [{ x: 1, y: 26}], top: [{x: 1, y: 3 }, {x: 40, y: 2}, {x: 81, y: 3 }], right: [{ x: 81, y: 26}], bottom: [{ x: 1, y: 51}, {x: 40, y: 51}, {x: 81, y: 51}] }
      }else if(nodeType === 'end') {
        nodePorts = { left: [{ x: 1, y: 34}], top: [{x: 1, y: 3 }, {x: 36, y: 2}, {x: 68, y: 3 }], right: [{ x: 68, y: 34}], bottom: [{ x: 1, y: 68}, {x: 36, y: 68}, {x: 68, y: 68}] }
      }else if(nodeType === 'task') {
        nodePorts = { left: [{ x: 1, y: 30}], top: [{x: 1, y: 3 }, {x: 50, y: 2}, {x: 95, y: 3 }], right: [{ x: 95, y: 30}], bottom: [{ x: 1, y: 58}, {x: 50, y: 58}, {x: 95, y: 58}] }
      }else if(nodeType === 'judge') {
        nodePorts = { left: [{ x: 1, y: 32}], top: [{x: 1, y: 3 }, {x: 42, y: 2}, {x: 82, y: 3 }], right: [{ x: 82, y: 32}], bottom: [{ x: 1, y: 65}, {x: 42, y: 65}, {x: 82, y: 65}] }
      }else {
        return
      }
      this.loadNodePortLayout(this.currentSelectNode, nodePorts)
    },

    // 加载节点连接桩并注册连接桩端口
    loadNodePortLayout(node, ports) {
      if(node.hasPorts()) return

      registerPortLayout(node.id, ports)

      let portNumbers = 0
      Object.keys(ports).forEach(item=> {
        portNumbers = portNumbers + ports[item].length
      })

      this.createNodePortLayout(node, portNumbers)
    },

    // 创建节点链接桩 并显示到画布
    createNodePortLayout(node, portNumbers) {
      node.prop('attrs/portsNumber', portNumbers)
      Array.from({ length: portNumbers }).forEach(() => {
        node.addPort({ group: 'sin', enabled: true })
      })
    },

    // 隐藏节点连接桩端口
    nodeHiddenPort(node) {
      node.prop('ports/groups/sin/attrs/circle', {  stroke: 'rgba(255, 255, 255, 0)', fill: 'rgba(255, 255, 255, 0)', magnet: false})
    },

    // 显示节点连接桩端口
     nodeShowPort(node) {
      node.prop('ports/groups/sin/attrs/circle', {  stroke: '#31d0c6', fill: '#fff', magnet: true})
     },

     getSelectNode() {
      const nodes = this.$antProcess.getAllSelectNode(this.graph)
      if(nodes == null || nodes.length <= 0) {
        this.$message.error('请选择节点')
        return
      }
      if(nodes.length > 1) {
        this.$message.error('请选择节点且只能选择一个')
        return
      }
      return this.currentSelectNode
     },

    //通过函数传递父级到画布节点组件
    getCurrentObj() {
      return this
    }
  }
}
</script>
<style lang="scss" scoped>
.palette-container {
  width: 100%;
  background-color: white;
  line-height: 40px;

  ::v-deep .palette {
    cursor: pointer;
    text-align: center;
    width: 100%;
    height: 60px;
    margin: 0px auto;
    line-height: 10px;
  }

  ::v-deep .palette-active {
    color: #409EFF;
  }

  ::v-deep .palette-active-disable {
    color: #b5b5c0;
  }
}
</style>